package core;

import org.apache.commons.lang3.StringUtils;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import utils.XmlUtils;

import javax.print.Doc;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * Created by zhangsen on 2016/10/25.
 */
public class MappingConfig {
    private static Set<String> excludeMethod;
    static{
        excludeMethod=new HashSet<String>();
        excludeMethod.add("wait");
        excludeMethod.add("equals");
        excludeMethod.add("toString");
        excludeMethod.add("hashCode");
        excludeMethod.add("getClass");
        excludeMethod.add("notify");
        excludeMethod.add("notifyAll");
    }

    public Map<String, DispatcherMapping> readMappingByXml(String filePath) {
        Document doc = XmlUtils.readXmlFile(filePath);
        Element root = doc.getRootElement();
        if (null == root) {
            return Collections.emptyMap();
        }
        if (!"mappings".equals(root.getName())) {
            return Collections.emptyMap();
        }
        String rootContext = "";
        Attribute rootContextAttr = root.getAttribute("context");
        if (null != rootContextAttr) {
            rootContext +="/"+rootContextAttr.getValue();
        }
        List<Element> children = root.getChildren();
        Map<String,DispatcherMapping> result=new HashMap<String, DispatcherMapping>();
        for (Element e : children) {
            String url;
            Attribute clazzAttr = e.getAttribute("class");
            Attribute context = e.getAttribute("context");
            if (null == clazzAttr) {
                return Collections.emptyMap();
            }
            if (null != context) {
                url = rootContext + "/" + context.getValue();
            } else {
                url = rootContext;
            }
            Class clazz = null;
            try {
                clazz = Class.forName(clazzAttr.getValue());
            } catch (ClassNotFoundException e1) {
                e1.printStackTrace();
            }

            url=url+"/"+clazz.getSimpleName()+"/";
            for(Method m:clazz.getMethods())
            {
                if(excludeMethod.contains(m.getName()))
                    continue;
                if(Modifier.PUBLIC!=m.getModifiers())
                    continue;
                boolean returnString;
                if(m.getReturnType().toString().equals("void"))
                {
                    returnString=false;
                }
                else if(m.getReturnType().equals(String.class))
                {
                    returnString=true;
                }
                else
                {
                    continue;
                }
                result.put(url+m.getName(),new DispatcherMapping(url+m.getName(),clazz,m,returnString));
            }

        }
        return result;
    }
}
